import com.google.common.collect.Lists;
import org.apache.commons.lang3.ArrayUtils;
import org.junit.Test;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * git地址

 https://gitee.com/yujianlong1988/java8andDisruptor.git
 * @author yujianlong
 * @create 2018-06-16 11:29
 **/
public class StreamTest0 {




	@Test
	public void streamInit0(){//流的遍历
		List<String> collec = Arrays.asList("a", "b", "c");
		Stream<String> stream = collec.stream();
		stream.forEach(System.out::println);
		stream.forEach(System.out::println);
//		stream.peek(System.out::println);
//		stream.peek(System.out::println);
//		collec.stream().forEach(System.out::println);
//		collec.stream().forEach(System.out::println);
	}

	@Test
	public void streamInit1(){//流的去重1
		List<String> collec = Arrays.asList("a", "a", "c");
		collec.stream().distinct().forEach(System.out::println);
	}


	public static class DisClass{
		private String name;
		public DisClass() {

		}
		public DisClass(String name) {
			this.name = name;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		@Override
		public String toString() {
			return "DisClass{" +
					"name='" + name + '\'' +
					'}';
		}

		@Override
		public boolean equals(Object o) {
			if (this == o) return true;
			if (o == null || getClass() != o.getClass()) return false;

			DisClass disClass = (DisClass) o;

			if (name != null ? !name.equals(disClass.name) : disClass.name != null) return false;

			return true;
		}

		@Override
		public int hashCode() {
			return name != null ? name.hashCode() : 0;
		}
	}

	@Test
	public void streamInit2(){//流的去重1
		List<String> collec = Arrays.asList("a", "a", "c");
		//不加上equals hashcode就不会去重
		collec.stream().map(DisClass::new).distinct().forEach(System.out::println);
	}


	@Test
	public void streamInit3(){//流变集合
		List<String> collec = Arrays.asList("a", "a", "c");
		//不加上equals hashcode就不会去重
		List<DisClass> collect = collec.stream().map(DisClass::new).distinct().collect(Collectors.toList());
		System.out.println(collect);
	}

	@Test
	public void streamInit4(){//流筛选过滤
		List<String> collec = Arrays.asList("a", "a", "c");
		//不加上equals hashcode就不会去重
		List<DisClass> collect = collec.stream().map(DisClass::new).distinct().
				filter(dis-> Objects.equals("a",dis.getName())).
				collect(Collectors.toList());
		System.out.println(collect);
	}

	@Test
	public void streamInit5(){//流模拟分页

		List<Integer> collect = IntStream.rangeClosed(1, 100).boxed().skip(10).limit(5).collect(Collectors.toList());
		System.out.println(collect);

	}

	@Test
	public void streamInit6(){//元素个数

		long count = IntStream.rangeClosed(1, 99).boxed().peek(System.out::println).count();
		System.out.println("count="+count);

	}

	@Test
	public void streamInit7(){//遍历流不能break

		IntStream.rangeClosed(1, 5).boxed()
				.forEach(i->{
					if (i==3) {
						return;//return 等同于continue
					}
					System.out.println(i);
				});
	}

	@Test
	public void streamInit9(){//流--集合变数组

		List<Integer> collect = IntStream.rangeClosed(1, 5).boxed().collect(Collectors.toList());
		Object[] objects = collect.stream().toArray();
		System.out.println(ArrayUtils.toString(objects));//但是这样没有类型
		Integer[] integers = collect.stream().toArray(Integer[]::new);
		Integer[] integers1 = collect.stream().toArray(size -> new Integer[size]);
		System.out.println(ArrayUtils.toString(integers));
		System.out.println(ArrayUtils.toString(integers1));

	}

	@Test
	public void streamInit10(){//流进行判断
		boolean b = IntStream.rangeClosed(1, 5).boxed().anyMatch(i -> i > 3);
		System.out.println(b);
		boolean b1 = IntStream.rangeClosed(1, 5).boxed().anyMatch(i -> i > 5);
		System.out.println(b1);
		boolean b2 = IntStream.rangeClosed(1, 5).boxed().allMatch(i -> i > 3);
		System.out.println(b2);
		boolean b3 = IntStream.rangeClosed(1, 5).boxed().noneMatch(i -> i > 8);
		System.out.println(b3);
	}


	@Test
	public void streamInit11(){//流进行排序
		List<Integer> collect = IntStream.rangeClosed(1, 50).boxed().collect(Collectors.toList());
		System.out.println(collect);
		Collections.shuffle(collect);//乱序
		System.out.println(collect);
		//排序
		List<Integer> collect1 = collect.parallelStream().sorted(Integer::compare).collect(Collectors.toList());
		System.out.println(collect1);

		//自定义排序
		Comparator<Integer> comparator=(i,j)->{
			if (i>j) {
				return 1;
			} else if (i==j) {
				return 0;
			} else {
				return -1;
			}
		};
		List<Integer> collect2 = collect.parallelStream().sorted(comparator).collect(Collectors.toList());
		System.out.println(collect2);
		//倒序
		List<Integer> collect3 = collect.parallelStream().sorted(comparator.reversed()).collect(Collectors.toList());
		System.out.println(collect3);

//		comparator.thenComparing() 可以多字段排序

	}

	@Test
	public void streamInit12(){//流进行map

		List<Integer> collect = IntStream.rangeClosed(1, 50).boxed().collect(Collectors.toList());
		List<String> collect1 = collect.stream().map(i -> i + "hello").collect(Collectors.toList());

		System.out.println(collect1);
	}


	@Test
	public void streamInit13(){//找首个元素或者任意元素

		List<Integer> collect = IntStream.rangeClosed(1, 50).boxed().collect(Collectors.toList());
		Integer first = collect.stream().findFirst().orElse(null);//
		System.out.println(first);

		Integer any = collect.parallelStream().findAny().orElse(null);//随机元素
		System.out.println(any);

	}

	@Test
	public void streamInit14(){//流的扁平化
		List<int[]> collect = IntStream.rangeClosed(1, 3).boxed().flatMap(i -> IntStream.rangeClosed(5, 6).boxed().map(j -> new int[]{i, j})).collect(Collectors.toList());
		collect.stream().forEach(a->{
			System.out.println(ArrayUtils.toString(a));
		});
	}

	@Test
	public void streamInit15(){//扁平化还原
		List<Integer> collect = IntStream.rangeClosed(1, 300).boxed().collect(Collectors.toList());
		List<List<Integer>> partition = Lists.partition(collect, 10);
		System.out.println(partition);
		//这里List<List<Integer>> 扁平化还原
		List<Integer> collect1 = partition.stream().flatMap(t -> t.stream()).collect(Collectors.toList());
		System.out.println(collect1);
	}


	@Test
	public void streamInit16(){//归约
		int sum = IntStream.rangeClosed(1, 100).sum();//求和1
		System.out.println(sum);

		int sum1 = IntStream.rangeClosed(1, 100).boxed().mapToInt(Integer::intValue).sum();//有区别的
		System.out.println(sum1);

//		BinaryOperator（T,T）->T
		Integer reduce = IntStream.rangeClosed(1, 100).boxed().reduce(0, (a, b) -> a + b);
		System.out.println(reduce);

		Optional<Integer> reduce1 = IntStream.rangeClosed(1, 100).boxed().reduce((a, b) -> a + b);
		System.out.println(reduce1.orElse(0));

		//bigdecimal的求和

		BigDecimal reduce2 = IntStream.rangeClosed(1, 100).boxed().map(i -> BigDecimal.valueOf(i)).reduce(BigDecimal.ZERO, BigDecimal::add);
		System.out.println(reduce2);


		//最大最小值
		Optional<Integer> max = IntStream.rangeClosed(1, 100).boxed().reduce(Integer::max);//实际上Integer::max BinaryOperator
		System.out.println(max.orElse(-1));
		Optional<Integer> min =IntStream.rangeClosed(1, 100).boxed().reduce(Integer::min);
		System.out.println(min.orElse(-1));



		//bigdecimal最大
		BinaryOperator<BigDecimal> cm1=(b1, b2)->{
			if (b1.compareTo(b2)>0) {
				return b1;
			} else if (b1.compareTo(b2)==0) {
				return b1;
			} else {
				return b2;
			}
		};
		//bigdecimal最小值
		BinaryOperator<BigDecimal> cm2=(b1, b2)->{
			if (b1.compareTo(b2)>0) {
				return b2;
			} else if (b1.compareTo(b2)==0) {
				return b1;
			} else {
				return b1;
			}
		};
		Optional<BigDecimal> bmax = IntStream.rangeClosed(1, 100).boxed().map(i -> BigDecimal.valueOf(i)).reduce(cm1);
		System.out.println(bmax.orElse(BigDecimal.ZERO));
		Optional<BigDecimal> bmin = IntStream.rangeClosed(1, 100).boxed().map(i -> BigDecimal.valueOf(i)).reduce(cm2);
		System.out.println(bmin.orElse(BigDecimal.ZERO));


	}


}
